/*************************************************************************

    SlkTree.h

*************************************************************************/

#ifndef _SLKTREE_H
#define _SLKTREE_H

#include <stdio.h>
#include <stdlib.h>
#include "SlkConstants.h"
#include "SlkString.h"

#undef push 
#undef pop

class SlkTreeI              // Interface for SlkParser
{

public:
    void reduce ( slk_size_t production_number ) {} 
    void predict ( slk_size_t production_number ) {}
};

class SlkTree : public SlkTreeI 
{
public:
    typedef struct _node2  {
        slk_size_t    token;
        int           value;
        struct  
        _node2  *parent,        // parent is the lhs of the production
                *child,         // first symbol on rhs of production
                *sibling,       // rest of the parent production is siblings
                *left_sibling;  // to go backwards
    
        _node2  ( slk_size_t  token2 ) {
            token = token2;
            parent = NULL;
            child = NULL;
            sibling = NULL;
            left_sibling = NULL;
        }
    } node2_t;
    
    typedef struct _stack
    {
        node2_t  **top ,
                 **end ,
                  *start [ 256 ];
    
        _stack() {
            top = start + 255;
            end = start + 255;
        }

        inline void push ( node2_t  *node2 )
        {
            if ( top > start) {
                *--top = node2;
            } else {
                puts ( "Calc: stack_t overflow" );
                exit(1);
            }
        }
        inline node2_t *pop ( void )
        {
            return  ( top < end ? *top++ : *top );
        }
    } stack_t;

public:

    SlkTree ( int display ); 

    void reduce ( slk_size_t production_number );   
    void predict ( slk_size_t production_number );

    void pre_order ( node2_t  *tree );
    void show_tree ( void );
    void show_parse_derivation ( void );
    void show_parse_derivation ( node2_t  *tree );

private:

    node2_t   *Root;
    node2_t   *Current;
    stack_t    Parse_stack;
    int        Display;

    node2_t   *make_node ( slk_size_t    token );
    node2_t   *make_LL_branch ( slk_size_t  production_number ); 
};



#endif

